import { RUNNING, KEY_MEM_RUNNING_CHILD, KEY_MEM_CALLED_CHILD } from '../constants';
import BaseNode from '../core/BaseNode';
import Tick from '../core/Tick';
import RandGate from './RandGate';

export default abstract class RandMemGate extends RandGate {

    onOpen(tick: Tick, ...args: any[]) {
        const result = this.pickArray(tick, ...args)
        tick.blackboard.set(KEY_MEM_RUNNING_CHILD, this.between(0, result.length - 1), tick.tree.id, this.id);
        const calledChildArray: number[] = []
        tick.blackboard.set(KEY_MEM_CALLED_CHILD, calledChildArray, tick.tree.id, this.id);
    }

    onTick(tick: Tick, ...args: any[]) {
        // 进行选取
        const result = this.pickArray(tick, ...args)
        // 检查pick的结果是否为空
        if (result.length === 0) {
            return this.defaultStatus()
        }
        // 当前索引
        let currentIndex = tick.blackboard.get(KEY_MEM_RUNNING_CHILD, tick.tree.id, this.id);
        // 检查索引
        if (currentIndex >= result.length) {
            return this.defaultStatus()
        }
        // 对应Node
        let currentNode: BaseNode | null = result[currentIndex]
        // 获取执行过的child数组
        const calledChild = tick.blackboard.get(KEY_MEM_CALLED_CHILD, tick.tree.id, this.id);
        // 当前数组
        const currentArray = result.filter((value, index) => { return calledChild.indexOf(index) < 0 })
        // 随机遍历次数
        // 判断排除的 和遍历过的 总数不为初始的长度 则异常
        if (currentArray.length + calledChild.length !== result.length) {
            throw `currentArray${currentArray} + calledChild=${calledChild} !== result.length`
        }
        while (currentNode) {
            currentIndex = result.indexOf(currentNode)
            const status = currentNode.execute(tick, ...args);
            // 判断是否为拦截
            if (this.isInterrupt(status)) {
                return status
            }
            // 判断是RUNNING,表示当前需要等待,不进行接下来的执行和判断,等下次onTick,直接从上次(本次)的RUNNING进行执行
            if (status === RUNNING) {
                tick.blackboard.set(KEY_MEM_RUNNING_CHILD, currentIndex, tick.tree.id, this.id);
                tick.blackboard.set(KEY_MEM_CALLED_CHILD, calledChild, tick.tree.id, this.id);
                return RUNNING;
            }

            // 判断是否[关注/不忽略]的状态
            if (!this.isIgnore(status)) {
                return status;
            }
            // 进行保存记录,并进行数组去除
            calledChild.push(currentIndex)
            currentArray.splice(currentArray.indexOf(currentNode), 1)
            // 获取下一个
            currentNode = this.pickNext(currentArray, calledChild.length, result.length);
        }
        // 返回默认类型
        return this.defaultStatus();
    }

    protected pickNext(array: BaseNode[], current: number, length: number): BaseNode | null {
        if (array.length === 0) return null
        if (current < 0 || current >= length) return null
        const index = array.length === 1 ? 0 : this.between(0, array.length - 1)
        return array[index]
    }
};
